﻿//Description:同步表结构类
//Copyright (c) : 通力凯顿（北京）系统集成有限公司
//Writer:Wangjh
//create Date:2023-8-9
//Rewriter:
//Rewrite Date:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BusinessRule.Common;
using System.Data;
using DatabaseAccess.DBUtility;
using System.Configuration;
using System.IO;
using Newtonsoft.Json;
using System.Collections;

namespace OracleTableSync
{
  public  class SyncTableStructure
  { 
      public static readonly String receivePath = ConfigurationManager.AppSettings["ReceivePath"].ToString();//接收文件路径
      public static readonly String receiveFileBak = ConfigurationManager.AppSettings["receiveFileBak"].ToString();//接收文件路径-历史
      public static readonly String receiveFileBakError = ConfigurationManager.AppSettings["receiveFileBakError"].ToString();//接收文件路径-历史，处理错误路径
        /// <summary>
        /// 执行入口
        /// </summary>
        public void Excute()
        {
            LogHelp.SetConfig();
            //处理推送
            DealSyncStructData();
            //处理接收
            ReceiveSyncStructData();
        }


        #region 处理推送表结构
        /// <summary>
        /// 获取需要同步的表结构
        /// </summary>
        /// <returns></returns>
        DataTable GetSyncTableStruct()
        {
            DataTable dt = DatabaseHelper.Query_ReturnDatTable(@"select * from (
select DBMS_METADATA.GET_DDL('TABLE',upper( st.tablename)) ddlsql,stt.id TableTaskID,stt.operatetype,
st.id,st.tablename,st.uniquecolname,st.nextsynctime,st.lastsynctime,st.sync_interval,stt.Createtime from sync_tableinfo st 
INNER JOIN Sync_TableTask stt on stt.tablename=st.tablename and stt.ishandle=0
where stt.OperateType =4
union all
select to_clob('DROP TABLE '||stt.tablename) ddlsql,stt.id TableTaskID,stt.operatetype,
st.id,st.tablename,st.uniquecolname,st.nextsynctime,st.lastsynctime,st.sync_interval,stt.Createtime from sync_tableinfo st 
INNER JOIN Sync_TableTask stt on stt.tablename=st.tablename and stt.ishandle=0
where stt.OperateType =5) order by Createtime");
            return dt;
        }

        /// <summary>
        /// 处理需要同步的表结构
        /// </summary>
      public   void DealSyncStructData()
        {
            DataTable dt = GetSyncTableStruct();

            foreach (DataRow dr in dt.Rows)
            {
                try
                {
                    DealSyncStructDataEach(dr);
                }
                catch (Exception ex)
                {
                    LogHelp.WriteError(ex.Message, ex);
                }
            }

        }

        /// <summary>
        /// 处理每张表结构
        /// </summary>
        /// <param name="dr"></param>
        void DealSyncStructDataEach(DataRow dr)
        {
            String sourceIP = CommonHelper.GetIP();
            List<Dictionary<String, Object>> jsonFile = new List<Dictionary<String, Object>>();
            List<ExcuteEntity> exs = new List<ExcuteEntity>();
            String pushID=Guid.NewGuid().ToString();
            //更新状态
            exs.Add(new ExcuteEntity()
            {
                TableName = "Sync_TableTask",
                ExcuteType = ExcuteEntity.ExcuteTypeEnum.update,
                ExcuteFileds = new List<FieldEntity>() { new FieldEntity("IsHandle", 1, FieldEntity.FieldTypeEnum.Numer), 
                   new FieldEntity("LastChangeTime",DateTime.Now, FieldEntity.FieldTypeEnum.Timestamp)},
                WhereFileds = new List<FieldEntity>() { new FieldEntity("Id", dr["TableTaskID"].ToString(), FieldEntity.FieldTypeEnum.Str) }
            });
            //插入推送表
            //exs.Add(new ExcuteEntity()
            //{
            //    TableName = "Sync_PushRecord",
            //    ExcuteType = ExcuteEntity.ExcuteTypeEnum.insert,
            //    ExcuteFileds = new List<FieldEntity>() { new FieldEntity("id", Guid.NewGuid().ToString(), FieldEntity.FieldTypeEnum.Str),
            //               new FieldEntity("PushID", pushID, FieldEntity.FieldTypeEnum.Str),
            //               new FieldEntity("TableChangeRecordID", "", FieldEntity.FieldTypeEnum.Str),
            //               new FieldEntity("TableName", dr["TableName"].ToString(), FieldEntity.FieldTypeEnum.Str),
            //               new FieldEntity("OldValue", DBNull.Value, FieldEntity.FieldTypeEnum.Clob),
            //               new FieldEntity("NewValue", DBNull.Value, FieldEntity.FieldTypeEnum.Clob),
            //               new FieldEntity("OperateType", dr["operatetype"], FieldEntity.FieldTypeEnum.Numer),
            //               new FieldEntity("SourceIP", sourceIP, FieldEntity.FieldTypeEnum.Str),
            //               new FieldEntity("TargetIP", targetIP, FieldEntity.FieldTypeEnum.Str),
            //               new FieldEntity("SyncStatus", 1, FieldEntity.FieldTypeEnum.Numer),
            //               new FieldEntity("CreateTime", DateTime.Now, FieldEntity.FieldTypeEnum.Timestamp),
            //               new FieldEntity("LastChangeTime", DateTime.Now, FieldEntity.FieldTypeEnum.Timestamp),
            //               new FieldEntity("UniqueColValue", DBNull.Value, FieldEntity.FieldTypeEnum.Str),
            //               new FieldEntity("UniqueColName", dr["UniqueColName"].ToString (), FieldEntity.FieldTypeEnum.Str),
            //               new FieldEntity("SqlText", dr["ddlsql"], FieldEntity.FieldTypeEnum.Clob),
            //           }
            //});
            DatabaseHelper.ExecuteDataByEntitys(exs);

            //存入json文件
            Dictionary<String, Object> eachJson = new Dictionary<String, Object>();
            eachJson.Add("type", "syncStruct");
            eachJson.Add("pushID", pushID);
            eachJson.Add("tableTaskID", dr["TableTaskID"].ToString());
            eachJson.Add("tableName", dr["TableName"].ToString());
            eachJson.Add("uniqueColName", dr["UniqueColName"].ToString());
            eachJson.Add("operateType", dr["operatetype"]);
            eachJson.Add("sourceIP", sourceIP);
            eachJson.Add("sqlText", dr["ddlsql"].ToString());

            jsonFile.Add(eachJson);
            String fileName = CommonHelper.writeJsonToFile(jsonFile, "STRUCT_" + jsonFile[0]["tableName"].ToString());
            CommonHelper.savePushFileRecord(jsonFile, fileName);//存入文件推送记录
        }
        #endregion

        #region 处理接收表结构
       /// <summary>
        /// 处理接收到的表结构
        /// </summary>
     public    void ReceiveSyncStructData()
        {
            DirectoryInfo mydir = new DirectoryInfo(receivePath);
            foreach (FileInfo fi in mydir.GetFiles())
            {
                try
                {
                    if (fi.Name.Contains("_STRUCT_"))
                    {
                        DealSyncData(fi);                    
                    }
                }
                catch (Exception ex)
                {
                    LogHelp.WriteError(ex.Message, ex);
                    //处理异常
                    CommonHelper.moveFile(fi, receiveFileBakError);
                }
            }
        }

        /// <summary>
        /// 处理接收到的数据
        /// </summary>
        /// <param name="dt"></param>
        void DealSyncData(FileInfo fi)
        {
            if (fi.Extension != ".json")
            {
                return;
            }
            List<ExcuteEntity> exs = new List<ExcuteEntity>();
            ArrayList sqlList = new ArrayList();
            String receiveID = Guid.NewGuid().ToString();//一次接收的id
            String targetIP = CommonHelper.GetIP();

            using (StreamReader streamReader = new StreamReader(fi.FullName))
            {
                string jsonText = streamReader.ReadToEnd();

                List<Dictionary<String, Object>> obj = JsonConvert.DeserializeObject<List<Dictionary<String, Object>>>(jsonText);
                foreach (Dictionary<String, Object> eachData in obj)
                {
                    if (eachData["type"].ToString() != "syncStruct")
                        continue;
                    ////插入接收表
                    //exs.Add(new ExcuteEntity()
                    //{
                    //    TableName = "Sync_ReceiveRecord",
                    //    ExcuteType = ExcuteEntity.ExcuteTypeEnum.insert,
                    //    ExcuteFileds = new List<FieldEntity>() { new FieldEntity("id", Guid.NewGuid().ToString(), FieldEntity.FieldTypeEnum.Str),
                    //       new FieldEntity("ReceiveID", receiveID, FieldEntity.FieldTypeEnum.Str),
                    //       new FieldEntity("TableChangeRecordID", DBNull.Value, FieldEntity.FieldTypeEnum.Str),
                    //       new FieldEntity("TableName", eachData["tableName"].ToString(), FieldEntity.FieldTypeEnum.Str),
                    //       new FieldEntity("OldValue", DBNull.Value, FieldEntity.FieldTypeEnum.Clob),
                    //       new FieldEntity("NewValue", DBNull.Value, FieldEntity.FieldTypeEnum.Clob),
                    //       new FieldEntity("OperateType", eachData["operateType"].ToString(), FieldEntity.FieldTypeEnum.Numer),
                    //       new FieldEntity("SourceIP", eachData["sourceIP"], FieldEntity.FieldTypeEnum.Str),
                    //       new FieldEntity("TargetIP", targetIP, FieldEntity.FieldTypeEnum.Str),
                    //       new FieldEntity("SyncStatus", 1, FieldEntity.FieldTypeEnum.Numer),
                    //       new FieldEntity("CreateTime", DateTime.Now, FieldEntity.FieldTypeEnum.Timestamp),
                    //       new FieldEntity("LastChangeTime", DateTime.Now, FieldEntity.FieldTypeEnum.Timestamp),
                    //       new FieldEntity("UniqueColValue", DBNull.Value, FieldEntity.FieldTypeEnum.Str),
                    //       new FieldEntity("UniqueColName",eachData["uniqueColName"].ToString (), FieldEntity.FieldTypeEnum.Str),
                    //       new FieldEntity("sqlText", eachData["sqlText"], FieldEntity.FieldTypeEnum.Clob),
                    //   }
                    //});

                    //判定表是否存在
                    int isExistTab = int.Parse(DatabaseHelper.GetSingle("SELECT COUNT(1) FROM USER_TABLES WHERE TABLE_NAME ='" + eachData["tableName"].ToString() + "'").ToString()) ;
                    if (eachData["operateType"].ToString() == "4" && isExistTab == 0)//创建表结构
                    {
                        //创建表结构
                        sqlList.Add(eachData["sqlText"].ToString());
                    }
                    else if (eachData["operateType"].ToString() == "5" && isExistTab == 1)//删除表结构
                    {
                        sqlList.Add(eachData["sqlText"].ToString());                    
                    }

                }
                CommonHelper.saveReceiveFileRecord(obj, fi.Name);//存入文件接收记录
            }
            if (sqlList.Count>0)
                DatabaseHelper.ExecuteSqlListTran(sqlList );
            //DatabaseHelper.ExecuteDataByEntitys(exs);
            //移动文件
            CommonHelper.moveFile(fi, receiveFileBak); 

        }

      #endregion
  }
}
